iT邦幫忙

0

從零打造輔大課表神器:Chrome Extension 開發實戰 30 天 - Day 22

  • 分享至 

  • xImage
  •  

Day 22:多時段處理與課程資料結構化

🎯 系列目標:用 30 天時間,從零開始打造一個專屬輔大學生的課表生成 Chrome 擴充功能

💻 作者:輔大智慧資安 412580084

📅 Day 22:多時段處理與課程資料結構化

🔗 課程系列回顧

昨天 Day 21 我們建立了基礎的時間轉換器,今天我們要進一步處理複雜的多時段課程,讓系統能正確解析像是「1,2,3」或「5~7」這樣的時段組合。

📋 學習目標

今天我們要完成:

  1. 🔄 實作複合時段解析功能
  2. 📚 建立課程時間處理器
  3. ⚠️ 實作基礎時間衝突檢測
  4. 🧪 測試多時段處理功能

🔄 複合時段解析功能

1.1 擴展 TimeConverter 類別

在原有的 TimeConverter 類別中新增多時段解析功能:

// 在 TimeConverter 類別中新增以下方法
class TimeConverter {
  // ... 原有的 constructor 和其他方法 ...

  // 解析複合時段 (如: "1,2,3" 或 "5~7")
  parsePeriods(periodString) {
    if (!periodString) return [];
    
    const periods = [];
    const parts = periodString.split(',');
    
    parts.forEach(part => {
      part = part.trim();
      
      // 處理範圍 (如: "5~7")
      if (part.includes('~')) {
        const [start, end] = part.split('~');
        const startOrder = this.periodTimeMap[start]?.order || parseInt(start);
        const endOrder = this.periodTimeMap[end]?.order || parseInt(end);
        
        for (let i = startOrder; i <= endOrder; i++) {
          const period = this.findPeriodByOrder(i);
          if (period) periods.push(period);
        }
      } else {
        // 單一時段
        periods.push(part);
      }
    });
    
    return periods;
  }

  // 根據順序查找時段
  findPeriodByOrder(order) {
    for (const [period, info] of Object.entries(this.periodTimeMap)) {
      if (info.order === order) {
        return period;
      }
    }
    return null;
  }
}

1.2 時間格式化顯示

新增格式化時間顯示的功能:

// 在 TimeConverter 類別中繼續新增
class TimeConverter {
  // ... 原有方法 ...

  // 格式化時間顯示
  formatTimeDisplay(timeInfo) {
    const dayNumber = this.convertDayToNumber(timeInfo.星期);
    const periods = this.parsePeriods(timeInfo.節次);
    
    const timeRanges = periods.map(period => {
      const info = this.convertPeriodToTime(period);
      return info.time;
    });
    
    return {
      day: this.convertNumberToDay(dayNumber),
      dayNumber: dayNumber,
      periods: periods,
      timeRanges: timeRanges,
      classroom: timeInfo.教室 || '未指定教室',
      fullDisplay: `星期${this.convertNumberToDay(dayNumber)} ${timeRanges.join(', ')} (${timeInfo.教室 || '未指定教室'})`
    };
  }
}

📚 課程時間處理器

2.1 建立 CourseTimeProcessor 類別

// 課程時間處理器
class CourseTimeProcessor {
  constructor() {
    this.timeConverter = new TimeConverter();
    this.log('📚 課程時間處理器初始化完成');
  }

  // 處理單一課程的所有時間
  processCourseTime(course) {
    if (!course.上課時間 || !Array.isArray(course.上課時間)) {
      this.log(`⚠️ 課程 ${course.課程名稱} 缺少時間資訊`);
      return course;
    }

    const processedTimes = course.上課時間.map((timeInfo, index) => {
      try {
        const formattedTime = this.timeConverter.formatTimeDisplay(timeInfo);
        
        return {
          ...timeInfo,
          索引: index,
          格式化資訊: formattedTime,
          時段列表: this.timeConverter.parsePeriods(timeInfo.節次)
        };
      } catch (error) {
        this.log(`❌ 處理課程 ${course.課程名稱} 第 ${index + 1} 個時間時出錯: ${error.message}`);
        return timeInfo;
      }
    });

    return {
      ...course,
      上課時間: processedTimes,
      總時段數: processedTimes.reduce((total, time) => {
        return total + (time.時段列表?.length || 0);
      }, 0)
    };
  }

  // 日誌輸出
  log(message) {
    console.log(`[CourseTimeProcessor] ${message}`);
  }
}

⚠️ 基礎時間衝突檢測

3.1 衝突檢測功能

// 在 TimeConverter 類別中新增衝突檢測
class TimeConverter {
  // ... 原有方法 ...

  // 檢查時間衝突
  checkTimeConflict(time1, time2) {
    if (!time1.星期 || !time2.星期 || time1.星期 !== time2.星期) {
      return false; // 不同星期不衝突
    }
    
    const periods1 = this.parsePeriods(time1.節次);
    const periods2 = this.parsePeriods(time2.節次);
    
    // 檢查是否有重疊的時段
    return periods1.some(p1 => periods2.includes(p1));
  }
}

🧪 測試多時段處理功能

4.1 測試函數

// 多時段處理測試
function testMultiPeriodProcessing() {
  console.log('🔄 開始測試多時段處理功能');
  
  const converter = new TimeConverter();
  
  // 測試複合時段解析
  const testComplexPeriods = ['1,2,3', '5~7', 'E1,E2', 'DN'];
  testComplexPeriods.forEach(periods => {
    const parsed = converter.parsePeriods(periods);
    console.log(`複合時段 ${periods} 解析為:`, parsed);
  });
  
  // 測試時間衝突檢測
  const time1 = { 星期: '一', 節次: '1,2' };
  const time2 = { 星期: '一', 節次: '2,3' };
  const conflict = converter.checkTimeConflict(time1, time2);
  console.log(`時間衝突檢測 (${time1.星期} ${time1.節次} vs ${time2.星期} ${time2.節次}):`, conflict);
  
  console.log('✅ 多時段處理測試完成');
}

4.2 程式碼清理說明

ℹ️ 重要提示:在加入新功能時,請將以下程式碼加到 content.js 的適當位置:

// 新增到 TimeConverter 類別中的方法:
// - parsePeriods() 方法
// - findPeriodByOrder() 方法  
// - formatTimeDisplay() 方法
// - checkTimeConflict() 方法

// 新增 CourseTimeProcessor 類別

// 新增測試函數:
// testMultiPeriodProcessing();

// 執行測試
testMultiPeriodProcessing();

然後重新載入插件後,我們在選課清單 的日誌中會看到以下輸出即成功
1


🎯 明日預告

今天我們建立了多時段處理能力,明天我們要將這些資料安全地儲存起來!


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言